import os
from pathlib import Path

from django.db.models import Count

from utils import alipay
from django.shortcuts import render,redirect,HttpResponse
from django.conf import settings

from utils.alipay import AliPay
from utils.encrypt import uid
from web import models
import datetime
from django_redis import get_redis_connection
import json
def index(request):

    return render(request,'index.html')

def price(request):
    """ 价格页面 """
    policy_list = models.PricePolicy.objects.filter(category=2)

    return render(request, 'web/price.html',{'policy_list':policy_list})

def payment(request,policy_id):
    """ 支付页面   form表单将参数policy_id通过action属性传递过来，这边直接用变量接收就可以使用 """
    # policy_id通过form表单中的action已经传递过来了，所以要根据policy_id在数据库中查询下这个套餐是否存在
    policy_object = models.PricePolicy.objects.filter(id=policy_id,category=2).first()
    if not policy_object:
        return redirect('/web/price/')

    number = request.GET.get('number','')

    if not number or not number.isdecimal():
        return redirect('/web/price/')
    elif int(number) < 1:
        return redirect('/web/price/')
    # print(policy_object)
    # 计算用户选择套餐的价格
    origin_price = int(number) * policy_object.price
    balance = 0
    _object = None
    if request.tracer.price_policy.category == 2:
        # 找到登录用户之前的订单，判断是否过期，没过期的话进行抵扣费用
        ## 在交易记录表中找到按照id倒序排列的交易记录，这个记录是用户最新的套餐
        _object = models.Transaction.objects.filter(user=request.tracer.user,status=2).order_by('-id').first()
        total_timedelta = _object.end_datetime - _object.start_datetime
        balance_timedelta = _object.end_datetime - datetime.datetime.now()
        if total_timedelta.days == balance_timedelta.days:
            balance = _object.price / total_timedelta.days * (balance_timedelta.days - 1) # 计算要抵扣的价格
        else:
            balance = _object.price / total_timedelta.days * balance_timedelta.days
    if balance >= origin_price: # 如果要抵扣的价格大于需要支付的价格，肯定是有问题的所以直接跳转
        return redirect('web/price.html')
    # 构造要传给前端的函数
    context = {
        'policy_id':policy_id,
        'number':number,
        'origin_price':origin_price,
        'balance':round(balance,2), # 抵扣的价格保留小数点后两位
        'total_price':origin_price - round(balance,2),
    }
    # 在下面的函数pay中，还需要再次使用校验好的数据：context，为了避免再次校验，就把校验后的数据context在传送到前端之前，存放到redis中
    conn = get_redis_connection()
    key = 'payment_{}'.format(request.tracer.user.mobile_phone) # 登录用户的手机号码当作key的数据
    data_value = json.dumps(context) # 把数据context通过json化后，当作value的数据
    ex = 60 * 30 # 超时的时间是秒，即把30分钟转换成秒当作超时时间
    conn.set(key,data_value,ex=ex)
    context['policy_object'] = policy_object
    context['transaction'] = _object
    return render(request,'web/payment.html',context)

def pay(request):
    """ 生成订单，并跳转支付 """
    # 取出放在redis中的数据
    conn = get_redis_connection() # 括号中是redis的名字，不输入的话默认连接的是default
    key = 'payment_{}'.format(request.tracer.user.mobile_phone) # 登录用户的手机号码当作key的数据
    context_string = conn.get(key)
    # 判断是否超时。如果超时的话就跳转到价格页面
    if not context_string:
        return redirect('web/price.html')
    # 获取的数据context_string是字节数据，所以需要再转换成json格式的数据
    context = json.loads(context_string.decode('utf-8'))
    # 获取的数据通过验证后，现在可以在数据库中生成交易记录，状态是待支付的状态
    # 利用随机字符串函数，生成订单号
    order_id = uid(request.tracer.user.mobile_phone)
    total_price = context['total_price']
    # 在数据库中生成交易记录的数据
    models.Transaction.objects.create(
        status = 1,
        order=order_id,
        user=request.tracer.user,
        price_policy_id=context['policy_id'],
        count=context['number'],
        price=total_price
    )

    # 跳转到支付宝支付。1.先生成一个支付的链接。2.跳转到这个链接。
    from utils.alipay import AliPay
    ali_pay = AliPay(
        appid=settings.ALI_APPID,
        app_notify_url = settings.ALI_NOTIFY_URL,
        return_url = settings.ALI_RETURN_URL,
        app_private_key_path=settings.ALI_PRI_KEY_PATH,
        alipay_public_key_path=settings.ALI_PUB_KEY_PATH
    )
    query_params = ali_pay.direct_pay(
        subject='系统会员',
        out_trade_no=order_id,
        total_amount=total_price,
    )
    pay_url = "{}?{}".format(settings.ALI_GATEWAY, query_params)
    return redirect(pay_url)


def pay_notify(request):
    """支付成功后跳转的页面和发送消息的页面 """
    ali_pay = AliPay(
        appid=settings.ALI_APPID,
        app_notify_url=settings.ALI_NOTIFY_URL,
        return_url=settings.ALI_RETURN_URL,
        app_private_key_path=settings.ALI_PRI_KEY_PATH,
        alipay_public_key_path=settings.ALI_PUB_KEY_PATH
    )
    # get请求只做跳转，不做数据库中数据的更新
    if request.method == 'GET':
        params = request.GET.dict()
        sign = params.pop('sign',None)
        status = ali_pay.verify(params,sign)
        return HttpResponse('支付成功')
    else:
        from urllib.parse import parse_qs
        body_str = request.body.decode('utf-8')
        post_data = parse_qs(body_str)
        post_dict = {}
        for k,v in post_data.items():
            post_dict[k] = v[0]
        sign = post_dict.pop('sign',None)
        status = ali_pay.verify(post_dict,sign)
        if status:
            current_datetime = datetime.datetime.now()
            out_trade_no = post_dict['out_trade_no']
            _object = models.Transaction.objects.filter(order=out_trade_no).first()
            _object.status = 2
            _object.start_datetime = current_datetime
            _object.end_datetime = current_datetime + datetime.timedelta(days=365 * _object.count)
            _object.save()
            return HttpResponse('success')
        return HttpResponse('POST返回')


























